package com.shiguiwu.springboot3.filter;

import cn.hutool.core.collection.CollUtil;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.select.GroupByElement;
import net.sf.jsqlparser.statement.select.OrderByElement;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectExpressionItem;
import net.sf.jsqlparser.statement.select.SelectItem;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Set;

/**
 * @description: 查询过滤器
 * @author: stone
 * @date: Created by 2023/7/21 20:16
 * @version: 1.0.0
 * @pakeage: com.shiguiwu.springboot3.filter
 */
@Component
@Slf4j
public class SelectFilter extends AbstractSqlFilter {


    @Override
    public boolean isSupport() {
        return this.getStatement() instanceof Select;
    }

    @Override
    public void handleSql(Set<String> cols) {
        PlainSelect plainSelect = (PlainSelect) ((Select) this.getStatement()).getSelectBody();
        List<SelectItem> selectItems = plainSelect.getSelectItems();
        for (SelectItem selectItem : selectItems) {
            if (selectItem instanceof SelectExpressionItem expressionItem) {
                Expression expression = expressionItem.getExpression();
                if (expression instanceof Column column) {
                    String columnName = column.getColumnName();
                    cols.add(columnName);
                }
            }
        }

        this.handleWhere(cols, plainSelect.getWhere());
        this.handleOrderBy(cols, plainSelect);
        this.handleGroupBy(cols, plainSelect);

    }

    private void handleGroupBy(Set<String> cols, PlainSelect plainSelect) {
        GroupByElement groupBy = plainSelect.getGroupBy();
        if (groupBy == null) {
            return;
        }
        ExpressionList expressionList = groupBy.getGroupByExpressionList();
        List<Expression> expressions = expressionList.getExpressions();
        expressions.forEach(x -> {
            if (x instanceof Column) {
                Column c = (Column) x;
                cols.add(c.getColumnName());
            }
        });
    }

    private void handleOrderBy(Set<String> cols, PlainSelect plainSelect) {
        List<OrderByElement> orderByElements = plainSelect.getOrderByElements();
        if (CollUtil.isEmpty(orderByElements)) {
            return;
        }
        orderByElements.forEach(x -> {
            if (x.getExpression() instanceof Column) {
                Column column = (Column) x.getExpression();
                cols.add(column.getColumnName());
            }
        });
    }

}
